移植性を最大限にするにはARNのパーティションをハードコーディングしてはいけない(中国リージョンの話)
こんにちは。サービス開発室の武田です。
みなさんARN(Amazon Resource Name)はおそらくご存じでしょう。こういうやつです。
arn:aws:iam::123456789012:role/my-role
さてCloudFormationやプログラムの中でARNを組み立てる場合、どういうコードを書いていますか?
たとえばCloudFormationの場合。
!Sub 'arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:vpc/${vpc}'
たとえばPythonの場合。
role_arn = f"arn:aws:iam::{account_id}:role/{role_name}",
これらのコードはおそらく、ほとんどの場合において問題なく動きます。しかし、それは通常のAWS商用リージョンに限った話です。
AWSのパーティション
AWSにはパーティションという概念があり、リージョンはいずれかのパーティションに属します。パーティションが異なると、IAMのクロスアカウントアクセスなどもできません。そしてパーティションが異なるとARNも異なります。
たとえばみなさんよくお世話になるポリシーとしてAdministratorAccess
があります。通常このポリシーのARNは次のようになっています。
arn:aws:iam::aws:policy/AdministratorAccess
しかしこれが中国リージョンの属するパーティションだと、次のように変わります。
arn:aws-cn:iam::aws:policy/AdministratorAccess
ARNの2セクション目がaws-cn
になっていますね。そう、実はここはaws
以外になりうるのです。
ちなみにBoto3で有効なパーティション一覧が取得できます。
>>> boto3.__version__ '1.26.161' >>> session = boto3.session.Session() >>> session.get_available_partitions() ['aws', 'aws-cn', 'aws-us-gov', 'aws-iso', 'aws-iso-b', 'aws-iso-e', 'aws-iso-f']
というわけで、普段aws
しか見ていないパーティションですが、実はこれだけ定義されています(なお、iso
が何かはよく知りません)。
パーティションを変数で置換する
AWS商用リージョン以外でも動作するようにするためには、ARNを構築する際にパーティションをハードコーディングしてはいけません。先ほどの例を書き直してみましょう。
たとえばCloudFormationの場合。
!Sub 'arn:${AWS::Partition}:ec2:${AWS::Region}:${AWS::AccountId}:vpc/${vpc}'
たとえばPythonの場合。
partition = session.get_partition_for_region(region_name=session.region_name) role_arn = f"arn:{partition}:iam::{account_id}:role/{role_name}",
get_partition_for_region()
関数は、指定したリージョンが属するパーティションを返す関数です。
>>> session.get_partition_for_region(region_name="ap-northeast-1") 'aws' >>> session.get_partition_for_region(region_name="cn-north-1") 'aws-cn'
そのため、処理対象のリージョンを引数に渡すことで、パーティションを得られます。これでパーティションが変わっても動作可能な、移植性の高いコードになりました。
まとめ
なんとなくARNの先頭部分、arn:aws:
までは固定だと思いがちですが、そうではないというお話でした。AWS商用リージョン以外を触る機会が出てきそうな方は、ぜひ覚えておいてください。